package arcomage;

import java.util.*;    // for list classes

/** This is an absract class for an Arcomage playing card. Actual methods for
 *  each card are defined by subclasses for each card.
 *  @author Joshua Barnes
 *  @version 13th December 2009
 */
public abstract class AmCard
{
    /** mirrors the getTitle method */
    public final String toString()
    {
        return "\""+getTitle()+"\"";
    }
    /** Compares the card titles (titles must be unique) */
    public final boolean equals(Object objIn)
    {
        AmCard cardIn;
        try
        {
            cardIn = (AmCard) objIn;
        }
        catch (Exception e)
        {
            /* if here, the type-cast failed, and we weren't passed an AmCard
            * object. */
            return false;
        }

        return getTitle().equals(cardIn.getTitle());
    }
    /** Returns a hashcode for the card. */
    public final int hashCode()
    {
        // derive our card's hashcode from that of it's title string.
        return getTitle().hashCode();
    }
    /** Returns the name (title) of the card. */
    public abstract String getTitle();
    /** Returns a verbose description of the card's effects and requirements*/
    public abstract String getDescription();
    /** Returns the card's suit (brick, gem or beast)*/
    public abstract AmCardSuit getSuit();
    /** Returns the cost to play the card */
    public abstract int getCost();
    /** Returns a boolean value denoting whether the card can be played in the
     *  current situation
     *  @param playersIn a List containing the game's current players
     *  @param callerIndexIn the list index of the player who wishes to play
     *         the card
     *  @param targetIndexIn the list index of the desired target of the card's
     *         effects (can be null if none)
     */
    public abstract boolean isPlayable(final List<AmPlayer> playersIn, int callerIndexIn, int targetIndexIn);
    /** Returns a boolean value denoting whether the card can be discarded in
     *  the current situation
     *  @param playersIn a List containing the game's current players
     *  @param callerIndexIn the list index of the player who holds the card.
     */
    public abstract boolean canDiscard(final List<AmPlayer> playersIn, int callerIndexIn);
    /** Carries out the effects of playing the card
     *  @param playersIn a List containing the game's current players
     *  @param callerIndexIn the list index of the player who uses (plays) the
     *         card.
     *  @param targetIndexIn the list index of the desired target of the card's
     *         effects (can be null if none)
     */
    public abstract void playEffects(List<AmPlayer> playersIn, int callerIndexIn, int targetIndexIn);
}
